#define	STOPPING_CONDITION	150 //seconds.
#define	DISCARD 55
void compute_performance(int sd, short event, void* arg);
double calculate_throughput(int bytes, double elapsed_time);
double measure_time_difference(struct timeval now, struct timeval past);

//----------for acceptor: thus prefixed by a------------------------------
typedef struct a_performance_t {

	int interval_num_packets_delivered;
	int total_num_packets_delivered;
	int total_num_redundant_packets_received;
	int interval_num_redundant_packets_received;
	int interval_num_packets_proposer_to_multicaster;
	int interval_num_paxos_packets_received;
	int total_num_instances;
	int highest_deliverable_inst_id;
	int interval_num_packets_lost;
	int interval_num_overwritten_insts;
	int total_num_overwritten_insts;
	int next_instance;
	int latency_counter;

	double total_time; // in mili seconds
	double interval_time; // in miliseconds.
	double interval_delivery_throughput;
	double total_delivery_throughput;
	double interval_latency;
	double total_latency;
	double interval_proposer_to_multicaster_latency;
	double interval_num_entrance;
	double interval_multicast_throughput;
	double interval_bytes_multicast;
	double interval_forward_throughput;
	double interval_bytes_forward;
	double interval_bytes_received;
	double interval_bytes_received_from_proposer;
	double interval_throughput_received_from_proposer;

} a_performance;
a_performance a_performances[STOPPING_CONDITION];
a_performance *a_interval_performance;
const char *a_performance_file;
const char *a_latency_file;

int a_next_performance_index;
void a_store_performance_in_file(const char * performance_file, const char * lat_file, int num_entries);
void a_store_performance_in_array(a_performance * performances_array, int * performance_index, a_performance *i_p);
void a_print_performance(a_performance *p);
void a_nulify_performance(a_performance *p);

//-----------for learner_proposer: thus prefixed by lp------------------------------
typedef struct lp_performance_t {

	int interval_num_packets_delivered;
	int interval_num_packets_received;
	int total_num_packets_received;
	int interval_num_packets_sent;
	int total_num_packets_delivered;
	int total_num_packets_sent;
	int total_num_holes;
	int interval_num_holes;
	int total_num_redundant_packets_received;
	int interval_num_redundant_packets_received;
	int highest_deliverable_inst_id;
	int interval_num_packets_lost;
	int interval_num_overwritten_insts;
	int total_num_overwritten_insts;
	int latency_counter;
	int next_to_propose_slot_number;
	int last_delivered;
	int last_gapless_delivered;
	int interval_repeated_requets;

	double total_time; // in mili seconds
	double interval_time; // in miliseconds.

	double total_delivery_throughput;
	double interval_delivery_throughput;
	double interval_sending_throughput;
	double total_sending_throughput;
	double interval_latency;
	double total_latency;
	double interval_num_entrance;
	double total_num_entrance;
	double interval_bytes_sent;
	double interval_throughput_sent;
	double interval_bytes_recvied;
	double interval_recv_throughput;

} lp_performance;

lp_performance lp_performances[STOPPING_CONDITION];
lp_performance *lp_interval_performance;
const char *lp_performance_file;
const char *lp_latency_file;
int lp_next_performance_index;

void lp_calculate_performance_over_all_interval_uptonow();
void lp_store_performance_in_file(const char * performance_file, const char * lat_file, int num_entries);
void lp_store_performance_in_array(lp_performance * performances_array, int * performance_index, lp_performance *i_p);
void lp_print_performance(lp_performance *p);
void lp_nulify_performance(lp_performance *p);

